<?php
/**
 * Concentre Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Concentre
 * @package    Concentre_Daemon
 * @copyright  
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    
 */

/**
 * @see Concentre_Daemon_Abstract
 */
require_once 'Concentre/Daemon/Abstract.php';

/**
 * @category   Concentre
 * @package    Concentre_Daemon
 * @copyright  
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Concentre_Daemon_Socket extends Concentre_Daemon_Abstract
{
    protected $_ipaddress = '77.73.40.15';
    protected $_port = '23';
    protected $_socket = null;
    protected $_maxclients = 10;
    protected $_clients = null;

    public function init()
    {
        $this->_socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        socket_set_option($this->_socket,SOL_SOCKET,SO_REUSEADDR,1);
        socket_bind($this->_socket, $this->_ipaddress, $this->_port) or die('Could not bind to address');
        socket_listen($this->_socket, $this->_maxclients);

        $this->log('starting daemon');
    }

    protected function _process()
    {
        $this->_clients = array('0' => array('socket' => $this->_socket));

        while (true) {
            $read[0] = $this->_socket;
        
            for ($i = 0; $i < 10; $i++ ) {
                if ($this->_clients[$i]['socket']  != null) {
                    $read[$i+1] = $this->_clients[$i]['socket'];
                } 
            }

            $ready = @socket_select($read,$write=NULL,$except=NULL, NULL);

            if(in_array($this->_socket,$read)) {
                for($i=1;$i<=10;$i++) {
                    if(!isset($this->_clients[$i])) {
                        $this->_clients[$i]['socket'] = socket_accept($this->_socket);
                        socket_getpeername($this->_clients[$i]['socket'],$ip);
                        $this->clients[$i]['ipaddress'] = $ip;

                        socket_write($this->_clients[$i]['socket'],"Welcome to my Custom Socket Server ");
                        socket_write($this->_clients[$i]['socket'],"There are " . (count($this->_clients) - 1) . " client(s) connected to this server. ");

                        echo("New client connected: " . $this->_clients[$i]['ipaddress'] . " ");
                        break;
                    } elseif($i == 10 - 1) {
                        echo("To many Clients connected! ");
                    }

                    if($ready < 1) {
                        continue;
                    }
                }
            }

            for($i=1;$i<11;$i++) {
                if(in_array($this->_clients[$i]['socket'],$read)) {
                    $data = @socket_read($this->_clients[$i]['socket'],1024000, PHP_NORMAL_READ);

                    if ($data === FALSE) {
                        unset($this->_clients[$i]);
                        echo "Client disconnected! ";
                        continue;
                    }

                    $data = trim($data);

                    if(!empty($data)) {
                        for($j=1;$j<11;$j++) {
                            if(isset($this->_clients[$j]['socket'])) {
                                if(($this->_clients[$j]['socket'] != $this->_clients[$i]['socket']) && ($this->_clients[$j]['socket'] != $this->_socket)) {
                                    echo($this->_clients[$i]['ipaddress'] . " is sending a message! ");
                                    socket_write($this->_clients[$j]['socket'],"[" . $this->_clients[$i]['ipaddress'] . "] says: " . $data . " ");
                                }
                            }
                        }

                        break;
                    } 
                }
            }
        }
    }

    public function stop() {
        parent::stop();
        @socket_close($this->_socket);
    }
}
